package com.winit.openapi.fsp.controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.SearchOperator;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.query.filter.SearchFilterHelper;
import com.winit.common.spi.SPIException;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.fsp.spi.common.Constant;
import com.winit.fsp.spi.loans.vo.Loan;
import com.winit.fsp.spi.repayment.RepaymentService;
import com.winit.fsp.spi.repayment.command.AdvanceRepaymentCommand;
import com.winit.fsp.spi.repayment.command.GetRepaymentAmountCommand;
import com.winit.fsp.spi.repayment.command.GetSurplusAmountCommand;
import com.winit.fsp.spi.repayment.command.QueryLoanPageCommand;
import com.winit.fsp.spi.repayment.vo.RepaymentAmount;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.ValidateUtil;

/**
 * 还款管理 <Change to the actual description of this class>
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * BW 		1.0  		2015-4-2 	Created
 * 
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping("/fsp/repayment")
public class RepaymentController extends BaseController {

    @Resource
    private RepaymentService repaymentService;

    /**
     * 提前还款-还款
     * 
     * @return
     * @author BW
     * @date 2015-4-2
     */
    @RequestMapping(value = "/advanceRepayment")
    public String advanceRepayment(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        AdvanceRepaymentCommand command = null;
        CommandContext ctx = CommandContext.getContext();
        Bpartner bpartner = (Bpartner) ctx.get(ApiConstant.API_BPARTNER);
        
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            try {
                command = JSONObject.toJavaObject(json, AdvanceRepaymentCommand.class);
                command.setCtx(ctx);
                command.setWinitPartnerId(Long.valueOf(bpartner.getcBpartnerId().intValue()));
            } catch (SPIException e) {
                throw new SPIException("javaBean 转换错误");
            }
            boolean flag = false;
            flag = repaymentService.advanceRepayment(command);
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("flag", flag);
            responseMsg.setData(data);
        } else {
            throw new SPIException("json格式错误");
        }
        return SUCCESS;
    }

    /**
     * 查询还款金额总计
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     * @author BW
     * @date 2015-4-2
     */
    @RequestMapping(value = "/getRepaymentAmount")
    public String getRepaymentAmount(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        GetRepaymentAmountCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            try {
                command = JSONObject.toJavaObject(json, GetRepaymentAmountCommand.class);
                command.setCtx(CommandContext.getContext());
            } catch (SPIException e) {
                throw new SPIException("javaBean 转换错误");
            }
            RepaymentAmount amount = repaymentService.getRepaymentAmount(command);
            if (amount != null) {
                responseMsg.setData(amount);
            }
        } else {
            throw new SPIException("json 格式错误");
        }
        return SUCCESS;
    }

    /**
     * 查询账户余额
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     * @author BW
     * @date 2015-4-2
     */
    @RequestMapping(value = "/getSurplusAmount")
    public String getSurplusAmount(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        GetSurplusAmountCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            try {
                command = JSONObject.toJavaObject(json, GetSurplusAmountCommand.class);
                command.setCtx(CommandContext.getContext());
            } catch (SPIException e) {
                throw new SPIException("javaBean 转换错误");
            }
            BigDecimal amount = repaymentService.getSurplusAmount(command);
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("surplusAmount", amount);
            responseMsg.setData(data);
        } else {
            throw new SPIException("json 格式错误");
        }
        return SUCCESS;
    }

    /**
     * 查询还款中的贷款单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     * @author BW
     * @date 2015-4-2
     */
    @RequestMapping(value = "/queryLoanPage")
    public String queryLoanPage(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        QueryLoanPageCommand command = new QueryLoanPageCommand();
        CommandContext ctx = CommandContext.getContext();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validpageParams(json);
            try {
                command = JSONObject.toJavaObject(json, QueryLoanPageCommand.class);
                Bpartner bpartner = (Bpartner) ctx.get(ApiConstant.API_BPARTNER);
                Searchable searchable = buildSearchPageParams(json);
                searchable.and(SearchFilterHelper.newCondition("partner_id",
                    SearchOperator.eq,
                    bpartner.getcBpartnerId()));
                searchable.and(SearchFilterHelper.newCondition("status",
                    SearchOperator.eq,
                    Constant.LoansStatusEnum.SRP.getVal()));
                command.setSearchable(searchable);
                command.setCtx(ctx);
            } catch (SPIException e) {
                throw new SPIException("javaBean 转换错误");
            }
            Page<Loan> page = repaymentService.queryLoanPage(command);
            if (page != null) {
                Map<String, Object> pageMap = new HashMap<String, Object>();
                pageMap.put("pageNo", page.getPageable().getPageNumber() + 1);
                pageMap.put("pageSize", page.getPageable().getPageSize());
                pageMap.put("totalCount", page.getTotalElements());

                Map<String, Object> data = new HashMap<String, Object>();
                data.put("list", page.getContent());
                data.put("pageParams", pageMap);
                responseMsg.setData(data);
            }

        } else {
            throw new SPIException("json 格式错误");
        }
        return SUCCESS;
    }

    private Searchable buildSearchPageParams(JSONObject json) {
        int pageNo = ApiConstant.PAGE_NO_DEFAULT;
        int pageSize = ApiConstant.PAGE_SIZE_DEFAULT;
        // pageParams
        if (json != null && json.containsKey("pageParams")) {
            JSONObject pageParams = json.getJSONObject("pageParams");
            // pageNo
            if (pageParams.containsKey("pageNo")) {
                pageNo = pageParams.getInteger("pageNo");
            }
            // pageSize
            if (pageParams.containsKey("pageSize")) {
                pageSize = pageParams.getInteger("pageSize");
            }
        }
        Searchable search = Searchable.newSearchable();
        search.setPage(pageNo - 1, pageSize);
        search.addSort(new Sort(Direction.DESC, "CREATED"));
        return search;
    }

    private void validpageParams(JSONObject json) {
        // pageParams
        if (json.containsKey("pageParams")) {
            Object obj = json.get("pageParams");
            if (obj instanceof JSONObject) {
                JSONObject pageParams = (JSONObject) obj;
                // pageNo
                ValidateUtil.validInteger(pageParams, "pageNo");
                // pageSize
                ValidateUtil.validInteger(pageParams, "pageSize");
                if (pageParams.containsKey("pageNo")) {
                    int pageNo = pageParams.getInteger("pageNo");
                    if (pageNo < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageNo");
                    }
                }
                if (pageParams.containsKey("pageSize")) {
                    int pageSize = pageParams.getInteger("pageSize");
                    if (pageSize < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
                    }
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageParams");
            }
        }
    }
}
